package com.michael.retail.commons.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.michael.retail.commons.constant.AuthConstant;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class JwtUtils {

    public static JSONObject getJwtPayload() {

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            String jwtPayload = ((ServletRequestAttributes) requestAttributes).getRequest()
                                                                              .getHeader(AuthConstant.JWT_PAYLOAD_KEY);
            return JSONUtil.parseObj(jwtPayload);
        }

        return null;
    }

    public static Long getUserId() {
        JSONObject payload = getJwtPayload();
        if (payload != null && payload.size() > 0) {
            return payload.getLong(AuthConstant.USER_ID_KEY);
        }
        return null;
    }

    public static String getUsername() {
        JSONObject payload = getJwtPayload();
        if (payload != null && payload.size() > 0) {
            return payload.getStr(AuthConstant.USER_NAME_KEY);
        }
        return null;
    }

    /**
     * 获取登录认证的客户端ID
     * <p>
     * 兼容两种方式获取Oauth2客户端信息（client_id、client_secret）
     * 方式一：client_id、client_secret放在请求路径中
     * 方式二：放在请求头（Request Headers）中的Authorization字段，且经过加密，例如 Basic Y2xpZW50OnNlY3JldA== 明文等于 client:secret
     */
    @SneakyThrows
    public static String getAuthClientId() {

        String clientId = null;

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            // 从请求路径中获取
            clientId = request.getParameter(AuthConstant.CLIENT_ID_KEY);
            if (StrUtil.isNotBlank(clientId)) {
                return clientId;
            }

            // 从请求头获取
            String basic = request.getHeader(AuthConstant.AUTHORIZATION_KEY);
            if (StrUtil.isNotBlank(basic) && basic.startsWith(AuthConstant.BASIC_PREFIX)) {
                basic = basic.replace(AuthConstant.BASIC_PREFIX, "");
                String basicPlainText = new String(new BASE64Decoder().decodeBuffer(basic), StandardCharsets.UTF_8);
                //client:secret
                clientId = basicPlainText.split(":")[0];
            }
        }
        return clientId;
    }

    public static List<String> getRoles() {
        JSONObject payload = getJwtPayload();
        if (payload != null && payload.size() > 0) {
            return payload.get(AuthConstant.JWT_AUTHORITIES_KEY, List.class);
        }
        return new ArrayList<>();
    }


}
